package cn.tedu.role.service.impl;

import cn.tedu.exception.ServiceException;
import cn.tedu.role.mapper.ManagerMapper;
import cn.tedu.role.mapper.RoleMapper;
import cn.tedu.role.pojo.dto.RoleDTO;
import cn.tedu.role.pojo.dto.RoleQueryDTO;
import cn.tedu.role.pojo.dto.UpdateRuleDTO;
import cn.tedu.role.pojo.entity.Manager;
import cn.tedu.role.pojo.entity.Role;
import cn.tedu.role.pojo.vo.RoleSelectListVO;
import cn.tedu.role.pojo.vo.RoleVO;
import cn.tedu.role.pojo.vo.RulesData;
import cn.tedu.role.service.RoleService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class RoleServiceImpl implements RoleService {
    int a = 1;
    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private ManagerMapper managerMapper;

    /**
     * 查询所有
     *
     * @return
     */
    @Override
    public List selectAll() {
        MPJLambdaWrapper<Role> wrapper = new MPJLambdaWrapper<>();
        wrapper.isNull(Role::getDeleteTime);
        wrapper.eq(Role::getStatus, "1");
        wrapper.select(Role::getId, Role::getName);
        List<Role> roles = roleMapper.selectList(wrapper);
        List<RoleSelectListVO> roleVOS = new ArrayList<>();
        for (Role role : roles) {
            RoleSelectListVO roleVO = new RoleSelectListVO();
            BeanUtils.copyProperties(role, roleVO);
            roleVOS.add(roleVO);
        }
        return roleVOS;
    }

    /**
     * 分页查询
     *
     * @param roleQueryDTO
     * @return
     */
    @Override
    public IPage<RoleVO> select(RoleQueryDTO roleQueryDTO) {
        //获取角色组
        MPJLambdaWrapper<Role> wrapper = new MPJLambdaWrapper<>();
        // 添加查询条件
        if (roleQueryDTO.getStatus() != null) {
            wrapper.eq("status", roleQueryDTO.getStatus());
        }

        if (roleQueryDTO.getName() != null) {
            wrapper.like("name", roleQueryDTO.getName());
        }

        wrapper.isNull("delete_time");

        Page<RoleVO> pageVO = roleMapper.selectJoinPage(new Page<>(roleQueryDTO.getPage(), roleQueryDTO.getPageNum()), RoleVO.class, wrapper);

        //通过角色组的ID去查找manager
        List<Integer> ids = new ArrayList<>();
        for (RoleVO roleVO : pageVO.getRecords()) {
            ids.add(roleVO.getId());
        }
        if (ids.isEmpty()) {
            return pageVO;
        }

        MPJLambdaWrapper<Manager> managerWrapper = new MPJLambdaWrapper<>();
        managerWrapper.in("role_id", ids);
        managerWrapper.select("id", "name", "role_id");
        List<Manager> managers = managerMapper.selectList(managerWrapper);

        //把查询出来的manager放回roleVO中(我知道很恶心,但是mybatis不支持join查询,mybatis-plus也不支持,mybatis-plus-join实现得又很恶心)
        for (Manager manager : managers) {
            log.debug("管理员信息:{}", manager);
            for (RoleVO roleVO : pageVO.getRecords()) {
                log.debug("角色组信息:{}", roleVO);
                if (roleVO.getId().equals(manager.getRoleId())) {
                    roleVO.setManagerCount(roleVO.getManagerCount() + 1);
                    List<Manager> managerList = roleVO.getManagers();
                    managerList.add(manager);
                    roleVO.setManagers(managerList);
                }
            }
        }
        return pageVO;
    }

    /**
     * 把Role实体类转换为RoleVO
     *
     * @param role
     * @return
     */
    public static RoleVO roleConvertRoleVO(Role role) {
        RoleVO roleVO = new RoleVO();
        roleVO.setId(role.getId());
        roleVO.setName(role.getName());
        roleVO.setStatus(role.getStatus());
        roleVO.setRules(role.getRules());
        roleVO.setCreateTime(role.getCreateTime());
        return roleVO;
    }


    /**
     * 更新或者创建
     *
     * @param roleDTO
     */
    @Override
    public void updateAOrInsert(RoleDTO roleDTO) {
        Role role = new Role();
        BeanUtils.copyProperties(roleDTO, role);
        if (roleDTO.getId() != null) {
            roleMapper.updateById(role);
        } else {
            role.setCreateTime(new Date());
            roleMapper.insert(role);
        }

    }

    /**
     * 通过ID删除(软删除)
     *
     * @param id
     */
    @Override
    public void delete(Integer id) {
        MPJLambdaWrapper<Manager> wrapper = new MPJLambdaWrapper<>();
        wrapper.eq("role_id", id);
        Long managerCount = managerMapper.selectCount(wrapper);
        if (managerCount > 0) {
            throw new ServiceException(400, "角色下有管理员,不可删除");
        }

        Role role = roleMapper.selectById(id);
        if (role != null) {
            role.setDeleteTime(new Date());
            roleMapper.updateById(role);
        }
    }

    /**
     * 修改状态
     *
     * @param id
     */
    @Override
    public void changeStatus(Integer id) {
        Role role = roleMapper.selectById(id);
        if (!"1".equals(role.getStatus())) {
            role.setStatus("1");
        } else {
            role.setStatus("-1");
        }
        roleMapper.updateById(role);
    }

    /**
     * 读取json文件
     *
     * @return
     * @throws IOException
     */
    public List<RulesData> getJsonData() {
        ObjectMapper objectMapper = new ObjectMapper();
        // JSON 文件路径
        String jsonFilePath = "/static/rules.json";
        ClassPathResource resource = new ClassPathResource(jsonFilePath);

        // 读取 JSON 文件
        StringBuilder jsonDataBuilder = new StringBuilder();
        List<RulesData> jsonDataList;
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                jsonDataBuilder.append(line);
            }

            // 解析 JSON 数据
            jsonDataList = objectMapper.readValue(jsonDataBuilder.toString(), objectMapper.getTypeFactory().constructCollectionType(List.class, RulesData.class));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return jsonDataList;
    }

    @Override
    public List getRules(Integer id) {
        if (id == null) {
            return getJsonData();
        }

        ObjectMapper objectMapper = new ObjectMapper();
        Role role = roleMapper.selectById(id);
        // 将 JSON 字符串解析为 List<String>
        List<String> stringList;
        try {
            stringList = objectMapper.readValue(role.getRules(), new TypeReference<List<String>>() {
            });
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        return stringList;
    }

    @Override
    public void updateRule(UpdateRuleDTO updateRuleDTO) {
        RoleDTO roleDTO = new RoleDTO();
        BeanUtils.copyProperties(updateRuleDTO, roleDTO);
        updateAOrInsert(roleDTO);
    }
}
